home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / pyxmpp / streamsasl.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  9KB  |  303 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. __revision__ = '$Id: streamsasl.py 678 2008-08-08 11:22:14Z jajcus $'
  5. __docformat__ = 'restructuredtext en'
  6. import base64
  7. import logging
  8. from pyxmpp.jid import JID
  9. from pyxmpp import sasl
  10. from pyxmpp.exceptions import StreamAuthenticationError, SASLNotAvailable, SASLMechanismNotAvailable, SASLAuthenticationFailed
  11. SASL_NS = 'urn:ietf:params:xml:ns:xmpp-sasl'
  12.  
  13. class StreamSASLMixIn(sasl.PasswordManager):
  14.     
  15.     def __init__(self, sasl_mechanisms = ()):
  16.         sasl.PasswordManager.__init__(self)
  17.         if sasl_mechanisms:
  18.             self.sasl_mechanisms = sasl_mechanisms
  19.         else:
  20.             self.sasl_mechanisms = []
  21.         self._StreamSASLMixIn__logger = logging.getLogger('pyxmpp.StreamSASLMixIn')
  22.  
  23.     
  24.     def _reset_sasl(self):
  25.         self.peer_sasl_mechanisms = None
  26.         self.authenticator = None
  27.  
  28.     
  29.     def _make_stream_sasl_features(self, features):
  30.         if self.sasl_mechanisms and not (self.authenticated):
  31.             ml = features.newChild(None, 'mechanisms', None)
  32.             ns = ml.newNs(SASL_NS, None)
  33.             ml.setNs(ns)
  34.             for m in self.sasl_mechanisms:
  35.                 if m in sasl.all_mechanisms:
  36.                     ml.newTextChild(None, 'mechanism', m)
  37.                     continue
  38.             
  39.         
  40.         return features
  41.  
  42.     
  43.     def _handle_sasl_features(self):
  44.         ctxt = self.doc_in.xpathNewContext()
  45.         ctxt.setContextNode(self.features)
  46.         ctxt.xpathRegisterNs('sasl', SASL_NS)
  47.         
  48.         try:
  49.             sasl_mechanisms_n = ctxt.xpathEval('sasl:mechanisms/sasl:mechanism')
  50.         finally:
  51.             ctxt.xpathFreeContext()
  52.  
  53.         if sasl_mechanisms_n:
  54.             self._StreamSASLMixIn__logger.debug('SASL support found')
  55.             self.peer_sasl_mechanisms = []
  56.             for n in sasl_mechanisms_n:
  57.                 self.peer_sasl_mechanisms.append(n.getContent())
  58.             
  59.         
  60.  
  61.     
  62.     def _process_node_sasl(self, xmlnode):
  63.         ns_uri = xmlnode.ns().getContent()
  64.         if ns_uri == SASL_NS:
  65.             self._process_sasl_node(xmlnode)
  66.             return True
  67.         
  68.         return False
  69.  
  70.     
  71.     def _process_sasl_node(self, xmlnode):
  72.         if self.initiator:
  73.             if not self.authenticator:
  74.                 self._StreamSASLMixIn__logger.debug('Unexpected SASL response: %r' % xmlnode.serialize())
  75.                 ret = False
  76.             elif xmlnode.name == 'challenge':
  77.                 ret = self._process_sasl_challenge(xmlnode.getContent())
  78.             elif xmlnode.name == 'success':
  79.                 ret = self._process_sasl_success(xmlnode.getContent())
  80.             elif xmlnode.name == 'failure':
  81.                 ret = self._process_sasl_failure(xmlnode)
  82.             else:
  83.                 self._StreamSASLMixIn__logger.debug('Unexpected SASL node: %r' % xmlnode.serialize())
  84.                 ret = False
  85.         elif xmlnode.name == 'auth':
  86.             mechanism = xmlnode.prop('mechanism')
  87.             ret = self._process_sasl_auth(mechanism, xmlnode.getContent())
  88.         
  89.         if xmlnode.name == 'response':
  90.             ret = self._process_sasl_response(xmlnode.getContent())
  91.         
  92.         if xmlnode.name == 'abort':
  93.             ret = self._process_sasl_abort()
  94.         else:
  95.             self._StreamSASLMixIn__logger.debug('Unexpected SASL node: %r' % xmlnode.serialize())
  96.             ret = False
  97.         return ret
  98.  
  99.     
  100.     def _process_sasl_auth(self, mechanism, content):
  101.         if self.authenticator:
  102.             self._StreamSASLMixIn__logger.debug('Authentication already started')
  103.             return False
  104.         
  105.         self.auth_method_used = 'sasl:' + mechanism
  106.         self.authenticator = sasl.server_authenticator_factory(mechanism, self)
  107.         r = self.authenticator.start(base64.decodestring(content))
  108.         if isinstance(r, sasl.Success):
  109.             el_name = 'success'
  110.             content = r.base64()
  111.         elif isinstance(r, sasl.Challenge):
  112.             el_name = 'challenge'
  113.             content = r.base64()
  114.         else:
  115.             el_name = 'failure'
  116.             content = None
  117.         root = self.doc_out.getRootElement()
  118.         xmlnode = root.newChild(None, el_name, None)
  119.         ns = xmlnode.newNs(SASL_NS, None)
  120.         xmlnode.setNs(ns)
  121.         if content:
  122.             xmlnode.setContent(content)
  123.         
  124.         if isinstance(r, sasl.Failure):
  125.             xmlnode.newChild(None, r.reason, None)
  126.         
  127.         self._write_raw(xmlnode.serialize(encoding = 'UTF-8'))
  128.         xmlnode.unlinkNode()
  129.         xmlnode.freeNode()
  130.         if isinstance(r, sasl.Success):
  131.             if r.authzid:
  132.                 self.peer = JID(r.authzid)
  133.             else:
  134.                 self.peer = JID(r.username, self.me.domain)
  135.             self.peer_authenticated = 1
  136.             self.state_change('authenticated', self.peer)
  137.             self._post_auth()
  138.         
  139.         if isinstance(r, sasl.Failure):
  140.             raise SASLAuthenticationFailed, 'SASL authentication failed'
  141.         
  142.         return True
  143.  
  144.     
  145.     def _process_sasl_challenge(self, content):
  146.         if not self.authenticator:
  147.             self._StreamSASLMixIn__logger.debug('Unexpected SASL challenge')
  148.             return False
  149.         
  150.         r = self.authenticator.challenge(base64.decodestring(content))
  151.         if isinstance(r, sasl.Response):
  152.             el_name = 'response'
  153.             content = r.base64()
  154.         else:
  155.             el_name = 'abort'
  156.             content = None
  157.         root = self.doc_out.getRootElement()
  158.         xmlnode = root.newChild(None, el_name, None)
  159.         ns = xmlnode.newNs(SASL_NS, None)
  160.         xmlnode.setNs(ns)
  161.         if content:
  162.             xmlnode.setContent(content)
  163.         
  164.         self._write_raw(xmlnode.serialize(encoding = 'UTF-8'))
  165.         xmlnode.unlinkNode()
  166.         xmlnode.freeNode()
  167.         if isinstance(r, sasl.Failure):
  168.             raise SASLAuthenticationFailed, 'SASL authentication failed'
  169.         
  170.         return True
  171.  
  172.     
  173.     def _process_sasl_response(self, content):
  174.         if not self.authenticator:
  175.             self._StreamSASLMixIn__logger.debug('Unexpected SASL response')
  176.             return 0
  177.         
  178.         r = self.authenticator.response(base64.decodestring(content))
  179.         if isinstance(r, sasl.Success):
  180.             el_name = 'success'
  181.             content = r.base64()
  182.         elif isinstance(r, sasl.Challenge):
  183.             el_name = 'challenge'
  184.             content = r.base64()
  185.         else:
  186.             el_name = 'failure'
  187.             content = None
  188.         root = self.doc_out.getRootElement()
  189.         xmlnode = root.newChild(None, el_name, None)
  190.         ns = xmlnode.newNs(SASL_NS, None)
  191.         xmlnode.setNs(ns)
  192.         if content:
  193.             xmlnode.setContent(content)
  194.         
  195.         if isinstance(r, sasl.Failure):
  196.             xmlnode.newChild(None, r.reason, None)
  197.         
  198.         self._write_raw(xmlnode.serialize(encoding = 'UTF-8'))
  199.         xmlnode.unlinkNode()
  200.         xmlnode.freeNode()
  201.         if isinstance(r, sasl.Success):
  202.             authzid = r.authzid
  203.             if authzid:
  204.                 self.peer = JID(r.authzid)
  205.             else:
  206.                 self.peer = JID(r.username, self.me.domain)
  207.             self.peer_authenticated = 1
  208.             self._restart_stream()
  209.             self.state_change('authenticated', self.peer)
  210.             self._post_auth()
  211.         
  212.         if isinstance(r, sasl.Failure):
  213.             raise SASLAuthenticationFailed, 'SASL authentication failed'
  214.         
  215.         return 1
  216.  
  217.     
  218.     def _process_sasl_success(self, content):
  219.         if not self.authenticator:
  220.             self._StreamSASLMixIn__logger.debug('Unexpected SASL response')
  221.             return False
  222.         
  223.         r = self.authenticator.finish(base64.decodestring(content))
  224.         if isinstance(r, sasl.Success):
  225.             self._StreamSASLMixIn__logger.debug('SASL authentication succeeded')
  226.             if r.authzid:
  227.                 self.me = JID(r.authzid)
  228.             else:
  229.                 self.me = self.me
  230.             self.authenticated = 1
  231.             self._restart_stream()
  232.             self.state_change('authenticated', self.me)
  233.             self._post_auth()
  234.         else:
  235.             self._StreamSASLMixIn__logger.debug('SASL authentication failed')
  236.             raise SASLAuthenticationFailed, 'Additional success data procesing failed'
  237.         return True
  238.  
  239.     
  240.     def _process_sasl_failure(self, xmlnode):
  241.         if not self.authenticator:
  242.             self._StreamSASLMixIn__logger.debug('Unexpected SASL response')
  243.             return False
  244.         
  245.         self._StreamSASLMixIn__logger.debug('SASL authentication failed: %r' % (xmlnode.serialize(),))
  246.         raise SASLAuthenticationFailed, 'SASL authentication failed'
  247.  
  248.     
  249.     def _process_sasl_abort(self):
  250.         if not self.authenticator:
  251.             self._StreamSASLMixIn__logger.debug('Unexpected SASL response')
  252.             return False
  253.         
  254.         self.authenticator = None
  255.         self._StreamSASLMixIn__logger.debug('SASL authentication aborted')
  256.         return True
  257.  
  258.     
  259.     def _sasl_authenticate(self, username, authzid, mechanism = None):
  260.         if not self.initiator:
  261.             raise SASLAuthenticationFailed, 'Only initiating entity start SASL authentication'
  262.         
  263.         while not self.features:
  264.             self._StreamSASLMixIn__logger.debug('Waiting for features')
  265.             self._read()
  266.         if not self.peer_sasl_mechanisms:
  267.             raise SASLNotAvailable, "Peer doesn't support SASL"
  268.         
  269.         if not mechanism:
  270.             mechanism = None
  271.             for m in self.sasl_mechanisms:
  272.                 if m in self.peer_sasl_mechanisms:
  273.                     mechanism = m
  274.                     break
  275.                     continue
  276.             
  277.             if not mechanism:
  278.                 raise SASLMechanismNotAvailable, "Peer doesn't support any of our SASL mechanisms"
  279.             
  280.             self._StreamSASLMixIn__logger.debug('Our mechanism: %r' % (mechanism,))
  281.         elif mechanism not in self.peer_sasl_mechanisms:
  282.             raise SASLMechanismNotAvailable, '%s is not available' % (mechanism,)
  283.         
  284.         self.auth_method_used = 'sasl:' + mechanism
  285.         self.authenticator = sasl.client_authenticator_factory(mechanism, self)
  286.         initial_response = self.authenticator.start(username, authzid)
  287.         if not isinstance(initial_response, sasl.Response):
  288.             raise SASLAuthenticationFailed, 'SASL initiation failed'
  289.         
  290.         root = self.doc_out.getRootElement()
  291.         xmlnode = root.newChild(None, 'auth', None)
  292.         ns = xmlnode.newNs(SASL_NS, None)
  293.         xmlnode.setNs(ns)
  294.         xmlnode.setProp('mechanism', mechanism)
  295.         if initial_response.data:
  296.             xmlnode.setContent(initial_response.base64())
  297.         
  298.         self._write_raw(xmlnode.serialize(encoding = 'UTF-8'))
  299.         xmlnode.unlinkNode()
  300.         xmlnode.freeNode()
  301.  
  302.  
  303.